package com.tuyenmonkey.textdecorator;

import com.tuyenmonkey.textdecorator.callback.OnTextClickListener;

import ohos.agp.components.Component;

import ohos.agp.components.Text;

import ohos.agp.text.Font;

import ohos.agp.text.RichText;

import ohos.agp.text.RichTextBuilder;

import ohos.agp.text.TextForm;

import ohos.multimodalinput.event.TouchEvent;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

/**
 * Created by Tuyen Nguyen on 12/24/16.
 */
public class TextDecorator {
    /**
     * 设置字体斜体
     */
    public static final int TYPE_ITALIC = 1001;
    /**
     * 设置字体加粗
     */
    public static final int TYPE_BOLD = 1002;

    private static final int INDEX = 0;
    private static final int NULL = 0;
    private static final int UNDERLINE = 1;
    private static final int TEXT_COLOR = 2;
    private static final int TEXT_BAG = 3;
    private static final int STRIKETHROUGH = 4;
    private static final int SUBSCRIPT = 5;
    private static final int SUPERSCRIPT = 6;
    private static final int SCALE_X = 7;
    private static final int ABSOLUTE_SIZE = 8;
    private static final int RELATIVE_SIZE = 9;
    private static final String REPLACE = "TEMP替换符";
    private static final String AE8668EA = "ae8668ea";

    /**
     * 文本控件
     */
    private Text textView;
    /**
     * 文本内容
     */
    private String content;
    /**
     * 备用替换文本
     */
    private String tempContent;
    /**
     * 是否对文本中每个设置的text进行设置样式
     */
    private boolean isContainAllText;
    /**
     * 字符串所在下标 集合
     */
    private final List<Integer> indexList;
    /**
     * 下标 字符串 键值对 集合
     */
    private final Map<Integer, String> indexTextMap;
    /**
     * 下标 富文本对象 键值对 集合
     */
    private final Map<Integer, TextForm> indexTextFormMap;
    /**
     * 监听事件 集合
     */
    private List<OnTextClickListener> listenerList;

    private final RichTextBuilder richTextBuilder;
    private int mResTextColorId;
    private int mResTextBagColorId;
    private float mProportion;
    private float mRelativeSize;
    private int mTextSize;
    private Font mFontBold;
    private Font mFontItalic;
    private int index = INDEX;
    private int indexPosition;

    /**
     * 设置的点击字符串 开始下标 集合
     */
    private List<Integer> clickStartList = new ArrayList<>();
    /**
     * 设置的点击字符串 结束下标 集合
     */
    private List<Integer> clickEndList = new ArrayList<>();

    private TextDecorator(Text textView, String content, boolean isContainAllText) {
        this.textView = textView;
        this.content = content;
        this.tempContent = content;
        this.isContainAllText = isContainAllText;

        indexList = new ArrayList<>();
        indexTextMap = new HashMap<>();
        indexTextFormMap = new HashMap<>();
        richTextBuilder = new RichTextBuilder();
        listenerList = new ArrayList<>();
    }

    /**
     * 初始化相关设置
     *
     * @param textView 文本控件
     * @param content  文本内容
     * @return TextDecorator
     */
    public static TextDecorator decorate(Text textView, String content) {
        return decorate(textView, content, false);
    }

    /**
     * 初始化相关设置
     *
     * @param textView         文本控件
     * @param content          文本内容
     * @param isContainAllText 是否查找文本中所有包含设置字符串的内容
     * @return TextDecorator
     */
    public static TextDecorator decorate(Text textView, String content, boolean isContainAllText) {
        return new TextDecorator(textView, content, isContainAllText);
    }

    /**
     * 设置下划线样式
     *
     * @param texts 设置的字符串
     * @return TextDecorator
     */
    public TextDecorator underline(final String... texts) {
        setData(UNDERLINE, new TextForm().setUnderline(true), texts);
        return this;
    }

    /**
     * 设置文本颜色样式
     *
     * @param resColorId 设置的字体颜色
     * @param texts      设置的字符串
     * @return TextDecorator
     */
    public TextDecorator setTextColor(final int resColorId, final String... texts) {
        this.mResTextColorId = resColorId;
        setData(TEXT_COLOR, new TextForm().setTextColor(resColorId), texts);
        return this;
    }

    /**
     * 设置文本背景色
     *
     * @param colorResId 设置的字体背景色
     * @param texts      设置的字符串
     * @return TextDecorator
     */
    public TextDecorator setBackgroundColor(final int colorResId, final String... texts) {
        this.mResTextBagColorId = colorResId;
        setData(TEXT_BAG, new TextForm().setTextBackgroundColor(colorResId), texts);
        return this;
    }

    /**
     * 设置文本删除线
     *
     * @param texts 设置的字符串
     * @return TextDecorator
     */
    public TextDecorator strikethrough(final String... texts) {
        setData(STRIKETHROUGH, new TextForm().setStrikethrough(true), texts);
        return this;
    }

    /**
     * 设置文本下标
     *
     * @param texts 设置的字符串
     * @return TextDecorator
     */
    public TextDecorator setSubscript(final String... texts) {
        setData(SUBSCRIPT, new TextForm().setSubscript(true), texts);
        return this;
    }

    /**
     * 设置文本上标
     *
     * @param texts 设置的字符串
     * @return TextDecorator
     */
    public TextDecorator setSuperscript(final String... texts) {
        setData(SUPERSCRIPT, new TextForm().setSuperscript(true), texts);
        return this;
    }

    /**
     * 设置字体样式
     *
     * @param type  字体样式
     * @param texts 设置的字符串
     * @return TextDecorator
     */
    public TextDecorator setFont(int type, final String... texts) {
        for (String text : texts) {
            Font.Builder fontBuilder = new Font.Builder(text);
            switch (type) {
                case TYPE_ITALIC:
                    fontBuilder.makeItalic(true);
                    break;
                default:
                    break;
            }
            this.mFontItalic = fontBuilder.build();

            if (!content.contains(text)) {
                continue;
            }

            // 定义循环,如果index的位置不是-1,就一值查找
            while ((index = content.indexOf(text, index)) != -1) {
                if (!indexList.contains(index)) {
                    indexList.add(index);
                    indexTextMap.put(index, text);
                    indexTextFormMap.put(index, new TextForm().setTextFont(mFontItalic));
                } else {
                    setTextForm(TYPE_ITALIC, indexTextFormMap.get(index));
                }
                // 每循环一次就要明确下一次查找的位置
                index = index + text.length();
            }
        }
        return this;
    }

    /**
     * 设置字体样式
     *
     * @param font  字体样式对象
     * @param texts 设置的字符串
     * @return TextDecorator
     */
    public TextDecorator setFont(Font font, final String... texts) {
        this.mFontBold = font;
        setData(TYPE_BOLD, new TextForm().setTextFont(font), texts);
        return this;
    }

    /**
     * 设置文本绝对字体大小
     *
     * @param size  字体大小
     * @param texts 设置的字符串
     * @return TextDecorator
     */
    public TextDecorator setAbsoluteSize(final int size, final String... texts) {
        this.mTextSize = size;
        setData(ABSOLUTE_SIZE, new TextForm().setTextSize(size), texts);
        return this;
    }

    /**
     * 设置文本相对字体大小
     *
     * @param proportion 相对字体大小
     * @param texts      设置的字符串
     * @return TextDecorator
     */
    public TextDecorator setRelativeSize(final float proportion, final String... texts) {
        this.mRelativeSize = proportion;
        setData(RELATIVE_SIZE, new TextForm().setRelativeTextSize(proportion), texts);
        return this;
    }

    /**
     * 设置文本缩放样式
     *
     * @param proportion 缩放大小
     * @param texts      设置的字符串
     * @return TextDecorator
     */
    public TextDecorator scaleX(final float proportion, final String... texts) {
        this.mProportion = proportion;
        setData(SCALE_X, new TextForm().setScaleX(proportion), texts);
        return this;
    }

    /**
     * 设置文本点击监听事件
     *
     * @param listener 监听事件对象
     * @param texts    设置的字符串
     * @return TextDecorator
     */
    public TextDecorator makeTextClickable(final OnTextClickListener listener, final String... texts) {
        for (String text : texts) {
            // 设置的字符串在文本中起始下标
            clickStartList.add(content.indexOf(text));
            // 设置的字符串在文本中结束的小标
            clickEndList.add(content.indexOf(text) + text.length());
            // 设置的字符穿对应的监听事件对象
            listenerList.add(listener);
        }
        return this;
    }

    private void setData(int type, TextForm textForm, final String... texts) {
        for (String text : texts) {
            if (!content.contains(text)) {
                continue;
            }
            // 拿到字符串 在文本中找到所有包含字符串的下标
            // 自定义循环如果index的位置不是-1 就一直查找
            while ((index = content.indexOf(text, index)) != -1) {
                if (!indexList.contains(index)) {
                    indexList.add(index);
                    indexTextMap.put(index, text);
                    indexTextFormMap.put(index, textForm);
                } else {
                    setTextForm(type, indexTextFormMap.get(index));
                }
                // 每循环一次就要确定下一次查找的位置
                index = index + text.length();
                // 如果设置了不查找文本所有设置字符串即结束循环
                if (!isContainAllText) {
                    break;
                }
            }
        }
    }

    private void setTextForm(int type, TextForm textForm) {
        switch (type) {
            case UNDERLINE:
                textForm.setUnderline(true);
                break;
            case TEXT_COLOR:
                textForm.setTextColor(mResTextColorId);
                break;
            case TEXT_BAG:
                textForm.setTextBackgroundColor(mResTextBagColorId);
                break;
            case STRIKETHROUGH:
                textForm.setStrikethrough(true);
                break;
            case SCALE_X:
                textForm.setScaleX(mProportion);
                break;
            case RELATIVE_SIZE:
                textForm.setRelativeTextSize(mRelativeSize);
                break;
            case ABSOLUTE_SIZE:
                textForm.setTextSize(mTextSize);
                break;
            case TYPE_ITALIC:
                textForm.setTextFont(mFontItalic);
                break;
            case TYPE_BOLD:
                textForm.setTextFont(mFontBold);
                break;
            default:
                break;
        }
    }

    /**
     * 创建富文本对象显示设置的文本相关样式
     */
    public void build() {
        int count = 0;
        List<String> list = sort();

        // 替换
        for (int k = 0; k < list.size(); k++) {
            if (list.get(k).equals(REPLACE)) {
                richTextBuilder.mergeForm(indexTextFormMap.get(indexList.get(count)));
                richTextBuilder.addText(indexTextMap.get(indexList.get(count)));
                richTextBuilder.revertForm();
                count++;
            } else {
                richTextBuilder.addText(list.get(k));
                richTextBuilder.revertForm();
            }
        }

        RichText richText = richTextBuilder.build();

        // 循环添加点击事件
        for (int i = 0; i < clickStartList.size(); i++) {
            indexPosition = i;
            richText.addTouchEventListener(new RichText.TouchEventListener() {
                @Override
                public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
                    if (touchEvent.getAction() == TouchEvent.PRIMARY_POINT_UP) {
                        listenerList.get(indexPosition).onClick(component, "");
                    }
                    return true;
                }
            }, clickStartList.get(i), clickEndList.get(i));
        }
        textView.setRichText(richText);
    }

    private List<String> sort() {
        int temp;
        // for循环选取第一个数
        for (int i = 0; i < indexList.size() - 1; i++) {
            // 原数组中，取出第一个数之后，相邻的另外一个数
            for (int j = 0; j < indexList.size() - 1 - i; j++) {
                // 比较两个整数的大小
                if (indexList.get(j) > indexList.get(j + 1)) {
                    temp = indexList.get(j);
                    indexList.set((j), indexList.get(j + 1));
                    indexList.set(j + 1, temp);
                }
            }
        }

        List<String> replace = replace();

        return replace;
    }

    private List<String> replace() {
        for (int strIndex : indexList) {
            tempContent = tempContent.replaceFirst(indexTextMap.get(strIndex), AE8668EA + REPLACE + AE8668EA);
            textView.setText(tempContent);
        }
        String[] strings = tempContent.split(AE8668EA);
        List<String> strList = removeNullStringArray(strings);
        return strList;
    }

    private List removeNullStringArray(String[] arrayString) {
        List<String> list1 = new ArrayList<String>();
        for (int i = 0; i < arrayString.length; i++) {
            if (arrayString[i] != null && arrayString[i].length() != 0) {
                // 过滤掉数组arrayString里面的空字符串
                list1.add(arrayString[i]);
            }
        }
        return list1;
    }
}
